/**
 * 
 */

/**
 * @author Parasuraman Ramakrishnan
 * Assignment Name: Homework1
 * Completed Date: 9/14/2009
 *
 */

package moreHealthModel.Student;


//CLASS INVARIANTS =====================================
//Student Class stores the Student Information and calculates the Overall Seriousness of 
//the Student based on their weight and Disease ratings. 
public class Student implements Person<String, Integer, Integer, Integer>

{

// CONSTANTS ==========================================
final static int MAX_HEIGHT=7;
final static int MIN_HEIGHT=1;

final static int MAX_WEIGHT=400;
final static int MIN_WEIGHT=20;

final static int MAX_AGE=40;
final static int MIN_AGE=1;

//ATTRIBUTES ==========================================
private String namex_;
private int agex_;
private int heightx_;
private int weightx_;
private int diseaseCodex_;

//When the Student Information are bizarre then set the value to True.
private boolean studentInfoStatus=false;

//CONSTRUCTORS ======================================
//ClInv1: studentName Cannot be null.
//ClInv2: Student Age Cannot be 0 or less.

public Student(String studentName, int studentAge, int studentHeight, int studentWeight, Disease d)
{
String trimmedStudentName=studentName;

if (studentName!=null)
	{
	    trimmedStudentName = studentName.trim();
	}
//The Student Age should be 1<=AGE<=40 and the Student Name should always be provided.
//Please go to ReadMe.txt to know more about Valid Student Information setup.
if (studentAge>=MIN_AGE && studentAge <= MAX_AGE && studentName!=null && !trimmedStudentName.isEmpty() && studentHeight>=MIN_HEIGHT && studentHeight<=MAX_HEIGHT && studentWeight>= MIN_WEIGHT && studentWeight<=MAX_WEIGHT && d!=null)
	{
		this.namex_ = studentName;
		this.agex_ = studentAge;
		this.heightx_= studentHeight;
		this.weightx_= studentWeight;
		this.diseaseCodex_= d.returndiseaseCode;
	}

else 
	{
		System.out.println(studentName+ ", one or more of your entered Information is invalid. Please read ReadMe.txt file for setting Valid Information.");
		studentInfoStatus=true;
		
	}
}

public Student(){}


//Return the status of whether the Student Name and Student Age is set.
public boolean getstudentInfoStatus()
	{
		return studentInfoStatus;
	}

public String GetName()
	{return namex_;}

public Integer GetAge()
	{return agex_;}

public Integer GetHeight()
	{return heightx_;}

public Integer GetWeight()
	{return weightx_;}


//The rating for 
//1. Diabetes is 5
//2. Heart Trouble is 4.
//3. Other is 2
public enum Disease
{
	diabetes (5),
	heartTrouble(4),
	other(2);
private final int returndiseaseCode;
Disease(int code)
{
	this.returndiseaseCode= code;
}

public int getDiseaseCode()
{return returndiseaseCode;}

}


public enum Weight
{
	Under(0),
	Normal(1),
	Overweight(2),
	InvalidWeight(999);
	
	private final int returnStudentWeigthLevel;
	Weight(int studentWeightLevel)
	{
		this.returnStudentWeigthLevel= studentWeightLevel;
	}
	
	public int getStudentWeightLevel()
		{
			return returnStudentWeigthLevel;
		}
	
}


//The ideal weight of the student for the height. 
//One(20) in the Enum means
//One---> 1 foot and 
//(20)--> 20 pounds.
public enum WeightByHeight

{
One(20),
Two(40),
Three(60),
Four(80),
Five(100),
Six(120),
Seven(140),
Invalid(999);

private final int weight;
WeightByHeight(int studentWeight)
	{
		this.weight= studentWeight;
	}

public int GetStudentWeight()
	{
		return weight;
	}
}

//METHODS ============================================

//INTENT: Set and return the WeightFactor By Height for the Student i.e if he is underweight/normal/overweight.
//PRECONDITIONS: 
//	anActualStudentheight: Student height used to get the Ideal Weight for the student's height.
//	anActualStudentweight: Student weight used to be compared with the Ideal WeightBy height for that student.

//POSTCONDITIONS: The WeightFactor is based by comparing the IdealWeight for the Height 
//versus the actualWeight of the Student.  

public Weight WeightFactorByHeight(int anActualStudentheight, int anActualStudentweight)
	{
		Weight weightByHeight= Weight.InvalidWeight;
		WeightByHeight wb;
		int idealStudentWeight=0;
		
		switch (anActualStudentheight)
		{
		case 1:
			wb= WeightByHeight.One;
			idealStudentWeight= wb.GetStudentWeight();
			break;
		case 2:
			wb= WeightByHeight.Two;
			idealStudentWeight= wb.GetStudentWeight();
			break;
		case 3:
			wb= WeightByHeight.Three;
			idealStudentWeight= wb.GetStudentWeight();
			break;
		case 4:
			wb= WeightByHeight.Four;
			idealStudentWeight= wb.GetStudentWeight();
			break;
		case 5:
			wb= WeightByHeight.Five;
			idealStudentWeight= wb.GetStudentWeight();
			break;
		case 6:
			wb= WeightByHeight.Six;
			idealStudentWeight= wb.GetStudentWeight();
			break;
		case 7:
			wb= WeightByHeight.Seven;
			idealStudentWeight= wb.GetStudentWeight();
			break;
		default:
			wb= WeightByHeight.Invalid;
			idealStudentWeight= wb.GetStudentWeight();
			break;
			
		}
	
	//POST-CONDITION starts here...
	if (anActualStudentheight>MAX_HEIGHT || anActualStudentheight<MIN_HEIGHT)
		weightByHeight= Weight.InvalidWeight;
	
	else if (anActualStudentweight>MAX_WEIGHT || anActualStudentweight<MIN_WEIGHT)
		weightByHeight= Weight.InvalidWeight;
	
	else if (anActualStudentweight<idealStudentWeight)
		weightByHeight= Weight.Under;
	
	else if (anActualStudentweight==idealStudentWeight)
		weightByHeight= Weight.Normal;
	
	else if (anActualStudentweight>idealStudentWeight)
		weightByHeight= Weight.Overweight;
	
	else 
		System.out.println("Something is screwed really bad!!");
		
		//POST-CONDITION is fulfilled here...
		return weightByHeight;
	}


//INTENT: Calculate the Overall Student Seriousness factor. 
//PRECONDITIONS: 
//	s: Student Object which contains Information about that Student.

//POSTCONDITIONS: Approximates the Values of the StudentHeight and StudentWeight. Gets the
//correct WeightFactor for the StudentsHeight and returns the Calculated Overall Seriousness. 

public int CalcSeriousnessFactor(Student s)
	{
		double aStudentActualHeight= s.GetHeight();
		double aStudentActualWeight= s.GetWeight();
		
		int approxStudentActualHeight=0;
		int approxStudentActualWeight=0;
		
		approxStudentActualHeight=(int) aStudentActualHeight;
		approxStudentActualWeight=(int) aStudentActualWeight;
		
		//If the Height is is more than 7.5 then approx to 8 else 7
		if (aStudentActualHeight-approxStudentActualHeight>0.5)
			{
				approxStudentActualHeight=approxStudentActualHeight+1;
			}

		//If the Weight is is more than 7.5 then approx to 8 else 7
		if (aStudentActualWeight-approxStudentActualWeight>0.5)
			{
				approxStudentActualWeight=approxStudentActualWeight+1;
			}
	
		//If the StudentHeight and Weight do not conform with Maximum/Minimum 
		//Height/Weight then indicate it by returning 0.
		if (approxStudentActualHeight<=MAX_HEIGHT && approxStudentActualHeight>=MIN_HEIGHT && approxStudentActualWeight<=MAX_WEIGHT && approxStudentActualWeight>=MIN_WEIGHT)
			{
		Weight weightFactorByStdHeight =WeightFactorByHeight(approxStudentActualHeight,approxStudentActualWeight);
		
		//(Disease seriousness ) + (Weight factor for this height)
		//int returnOvrllSeriousnessFac= aD.returndiseaseCode +weightFactorByStdHeight.returnStudentWeigthLevel;
		int returnOvrllSeriousnessFac= s.diseaseCodex_+weightFactorByStdHeight.returnStudentWeigthLevel;
		
		return returnOvrllSeriousnessFac;
			}
		
		else 
			return 0;
	}


}


